package com.example.core.network

import android.content.Context
import android.util.Log
import com.franmontiel.persistentcookiejar.PersistentCookieJar
import com.franmontiel.persistentcookiejar.cache.SetCookieCache
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor
import com.ihsanbal.logging.Level
import com.ihsanbal.logging.LoggingInterceptor
import okhttp3.Authenticator
import okhttp3.Cache
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit

/**
 * Created by zhudongao
 * Desc
 * Date 2020/10/24
 */
object HttpClient {

    private lateinit var appContext: Context
    private lateinit var baseUrl: String
    private val cookiePersistor by lazy {
        SharedPrefsCookiePersistor(appContext)
    }
    private val cookieJar by lazy {
        PersistentCookieJar(SetCookieCache(), cookiePersistor)
    }

    private val logInterceptor = LoggingInterceptor.Builder()
        .setLevel(Level.BASIC)
        .log(Log.VERBOSE)
        .tag("NetClient")
        .build()

    private val netLogInterceptor = LoggingInterceptor.Builder()
        .setLevel(Level.BASIC)
        .log(Log.VERBOSE)
        .tag("NetworkHttpClient")
        .build()

    private lateinit var retrofit: Retrofit
    lateinit var okHttpClient: OkHttpClient
    lateinit var clientBuild:OkHttpClient.Builder

    fun <T> apiService(apiClazz: Class<T>): T {
        return retrofit.create(apiClazz)
    }

    fun clearCookie() = cookieJar.clear()

    fun hasCookie() = cookiePersistor.loadAll().isNotEmpty()

    fun init(context: Context, baseUrl: String):HttpClient {
        this.appContext = context
        this.baseUrl = baseUrl
        val cacheDir = File(context.cacheDir, "ok_http_cache")
        val cache = Cache(cacheDir, 10 * 1024 * 1024)
        clientBuild = OkHttpClient.Builder()
            .connectTimeout(20, TimeUnit.SECONDS)
            .readTimeout(5, TimeUnit.MINUTES)
            .writeTimeout(5, TimeUnit.MINUTES)
            .retryOnConnectionFailure(true)
            .cache(cache)
            .cookieJar(cookieJar)
        return this
    }

    fun build(openDefaultLog:Boolean) {
        if (openDefaultLog) {
            clientBuild.addNetworkInterceptor(netLogInterceptor)
        }
        okHttpClient = clientBuild.build()
        retrofit = Retrofit.Builder()
            .client(okHttpClient)
            .baseUrl(baseUrl)
            .addConverterFactory(MoshiConverterFactory.create(MoshiHelper.moshi))
            .build()
    }

    fun addInterceptor(interceptor: Interceptor):HttpClient{
        clientBuild.addInterceptor(interceptor)
        return this
    }

    fun addNetworkInterceptor(interceptor: Interceptor):HttpClient{
        clientBuild.addNetworkInterceptor(interceptor)
        return this
    }

    fun authenticator(authenticator: Authenticator):HttpClient {
        clientBuild.authenticator(authenticator)
        return this
    }
}